
/**
 * 固伤技能计算 
 * @param {*} fight_data 
 * @param {*} src_unit 
 * @param {*} target_unit 
 * @param {*} skill_name 技能名称
 * @param {*} damage_ratio 伤害系数
 * @param {*} consummer 是否消耗
 * @returns 
 */
export function computing_final_skill(fight_data, src_unit, target_unit, skill_name, damage_ratio, consummer = true) {
	console.debug(`固伤技能计算 => 编号: ${src_unit["编号"]} 类型: ${src_unit["类型"]} 气血: ${src_unit["气血"]} 目标编号: ${target_unit["编号"]} 技能：${skill_name}`);

	let skill_level = G.FightUnitUtils.get_unit_skill_level(src_unit, skill_name);

	let skill_data = G.SkillData.default[skill_name];

	let target_count = 1;

	// 目标数量计算 从技能配置取
	if (skill_data["目标"]) {
		target_count = skill_data["目标"](fight_data, src_unit, skill_level);
	} else {
		console.debug(`固伤技能 ${skill_name} 未定义目标计算`);
	}

	if (target_count === 0) {
		console.debug(`固伤技能 ${skill_name} 获取技能目标数为零，跳过计算 `);
		return;
	}

	let target_list = G.FightUtils.get_enemy_team_group_survive_unit(fight_data, src_unit, target_unit, target_count);

	if (target_list.length === 0) {
		return;
	}
	target_count = target_list.length;

	if (consummer) {
		let consummer_value = 0;
		let consummer_type = "";
		if (skill_data && skill_data["消耗"]) {
			let res = skill_data["消耗"](fight_data, src_unit, 1);
			if (res) {
				consummer_value = res[0];
				consummer_type = res[1];
			}
		}
		// 如果需要的消耗类型不够则行动失败
		if (!G.FightUnitUtils.excute_unit_skill_consummer(fight_data, src_unit, consummer_type, consummer_value, skill_name)) {
			fight_data["战斗流程"].push({ "流程": 6, "战斗提示": { "内容": "行动失败", "编号": src_unit["编号"] } });
			return;
		}
	}

	fight_data["战斗流程"].push({ "流程": 200, "攻击方": src_unit["编号"], "被攻击": [], "提示": { "允许": true, "类型": "法术", "名称": `${src_unit["名称"]}使用了${skill_name}` }, "技能提示": { "内容": `【固伤】${skill_name}`, "编号": src_unit["编号"] } })

	//循环前计算 独立算法

	if (src_unit["类型"] === "玩家") {
		if (skill_data["固伤攻击前触发"]) {
			skill_data["固伤攻击前触发"](fight_data, src_unit, target_unit, skill_level);
		}
		if (!fight_data["PK战斗"]) {
			src_unit["统计数据"]["施法"] += 1;
		}
	}

	// 依次计算对每个目标的攻击流程
	for (let index = 0; index < target_list.length; index++) {
		let target = target_list[index];
		computing_final_skill_process(fight_data, src_unit, target, skill_name, skill_level, target_list, index, damage_ratio);
	}

	//结尾流程
	src_unit["被反弹"] = undefined;
	// 技能结尾附加计算
	if (skill_data["结尾附加"]) {
		console.debug(`固伤技能结尾附加 : ${src_unit["编号"]} ${skill_name} ${target_list.length}`);
		skill_data["结尾附加"](fight_data, src_unit, target_list, skill_name, skill_level, target_list.length);
	}
}

/**
 * 固伤技能计算1 固伤技能流程计算
 * @param {*} fight_data 
 * @param {*} src_unit 
 * @param {*} target_unit 
 * @param {*} target_list 
 * @param {*} skill_name 
 * @param {*} skill_level 
 * @param {*} damage_ratio 
 * @returns 
 */
function computing_final_skill_process(fight_data, src_unit, target_unit, skill_name, skill_level, target_list, index, damage_ratio) {
	fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"].push({ "特效": [skill_name], "编号": target_unit["编号"] })
	let cureent_index = fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"].length - 1;

	// 特技名称
	if (ex_skill[skill_name]) {
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["特技名称"] = skill_name;
	}

	let damage = 1;

	let skill_data = G.SkillData.default[skill_name];

	if (target_unit["法术状态"]["天地同寿"]) {
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["免疫"] = true;
		return;
	}

	if (target_unit["法术状态"]["分身术"] && target_unit["法术状态"]["分身术"]["破解"] === undefined) {
		target_unit["法术状态"]["分身术"]["破解"] = 1;
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["免疫"] = true;
		return;
	}

	// 吸收
	let xs = skill_data["吸收"];
	// 弱点
	let rd = skill_data["弱点"];;

	// 执行技能算法
	if (skill_data["固伤算法"]) {
		let res = skill_data["固伤算法"](fight_data, src_unit, target_unit, skill_level, target_list, index);
		// 技能被躲避
		if (res === false) {
			return;
		}
		damage = res;
	} else {
		console.warn(`固伤技能 ${skill_name} 未定义固伤算法`);
	}

	// 躲避计算
	if (src_unit["门派"] !== "龙宫" && ex_skill[skill_name] === undefined) {
		if (target_unit["门派"] === "天宫") {
			let gl = 15;
			if (target_unit["法术状态"]["颠倒五行"]) {
				gl = gl + 7;
				if (target_unit["法术状态"]["颠倒五行"]["增加躲避"]) {
					gl = gl + 15;
					if (gl >= 25) {
						gl = 25;
					}
				}
			}
			if (target_unit["软烟罗锦"]) {
				gl = gl + target_unit["软烟罗锦"];
			}
			if (G.RandomUtils.chance(gl)) {
				fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["躲避"] = true;
				return;
			}
		} else {
			let gl = 1
			if (target_unit["法术状态"]["颠倒五行"]) {
				gl = 8
				if (target_unit["法术状态"]["颠倒五行"]["增加躲避"]) {
					gl = 16
				}
			}
			if (target_unit["软烟罗锦"]) {
				gl = gl + target_unit["软烟罗锦"];
			}
			if (G.RandomUtils.chance(gl)) {
				fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["躲避"] = true;
				return;
			}
		}
	}

	// 攻击单位法术状态对法术伤害结果的影响
	for (const key in src_unit["法术状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["攻击法伤结果"]) {
			let res = G.SkillData.default[key]["攻击法伤结果"](fight_data, src_unit, target_unit, damage);
			if (res) {
				return res;
			}
		}
	}

	// 被攻击单位法术状态对法术伤害结果的影响
	for (const key in target_unit["法术状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["被攻击法伤结果"]) {
			let res = G.SkillData.default[key]["被攻击法伤结果"](fight_data, src_unit, target_unit, damage);
			if (res) {
				return res;
			}
		}
	}

	// 攻击单位奇经八脉对法术伤害结果的影响
	if (src_unit["奇经八脉"] && src_unit["门派"] !== "无门派") {
		let sects_jing_mai_data = G.JingMaiData.default[src_unit["门派"]];
		//门派统一处理
		if (sects_jing_mai_data["攻击法伤结果"]) {
			sects_jing_mai_data["攻击法伤结果"](fight_data, src_unit, target_unit, damage);
		}
		// 已点经脉
		for (const key in src_unit["奇经八脉"]) {
			if (src_unit["奇经八脉"][key] === 1 && sects_jing_mai_data[key] && sects_jing_mai_data[key]["攻击法伤结果"]) {
				sects_jing_mai_data[key]["攻击法伤结果"](fight_data, src_unit, target_unit, damage);
			}
		}
	}

	// 被攻击单位奇经八脉对法术伤害结果的影响
	if (target_unit["奇经八脉"] && target_unit["门派"] !== "无门派") {
		let sects_jing_mai_data = G.JingMaiData.default[target_unit["门派"]];
		//门派统一处理
		if (sects_jing_mai_data["被攻击法伤结果"]) {
			sects_jing_mai_data["被攻击法伤结果"](fight_data, src_unit, target_unit, damage);
		}
		// 已点经脉
		for (const key in target_unit["奇经八脉"]) {
			if (target_unit["奇经八脉"][key] === 1 && sects_jing_mai_data[key] && sects_jing_mai_data[key]["被攻击法伤结果"]) {
				sects_jing_mai_data[key]["被攻击法伤结果"](fight_data, src_unit, target_unit, damage);
			}
		}
	}

	// 攻击单位法术状态对伤害结果的影响
	for (const key in src_unit["法术状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["攻击伤害结果"]) {
			console.debug(`攻击伤害结果 ===>  法术状态 ${key}`);
			G.SkillData.default[key]["攻击伤害结果"](fight_data, src_unit, target_unit, damage);
		}
	}

	// 被攻击单位法术状态对伤害结果的影响
	for (const key in target_unit["法术状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["被攻击伤害结果"]) {
			console.debug(`被攻击伤害结果 ===>  法术状态 ${key}`);
			G.SkillData.default[key]["被攻击伤害结果"](fight_data, src_unit, target_unit, damage);
		}
	}

	// 被攻击单位奇经八脉对伤害结果的影响
	if (target_unit["奇经八脉"] && target_unit["门派"] !== "无门派") {
		let sects_jing_mai_data = G.JingMaiData.default[target_unit["门派"]];
		// 已点经脉
		for (const key in target_unit["奇经八脉"]) {
			if (target_unit["奇经八脉"][key] === 1 && sects_jing_mai_data[key] && sects_jing_mai_data[key]["被攻击伤害结果"]) {
				console.debug(`被攻击伤害结果 ===>  奇经八脉 ${key}`);
				sects_jing_mai_data[key]["被攻击伤害结果"](fight_data, src_unit, target_unit, damage);
			}
		}
	}

	//  攻击单位内丹属性对伤害结果的影响
	for (const key in src_unit["内丹属性"]) {
		let nei_dan_data = G.NeiDanData.default[key]
		if (nei_dan_data && nei_dan_data["攻击伤害结果"]) {
			console.debug(`攻击伤害结果 ===> 内丹属性 ${key}`);
			nei_dan_data["攻击伤害结果"](fight_data, src_unit, target_unit, damage);
		}
	}

	//  被攻击单位内丹属性对伤害结果的影响
	for (const key in target_unit["内丹属性"]) {
		let nei_dan_data = G.NeiDanData.default[key]
		if (nei_dan_data && nei_dan_data["被攻击伤害结果"]) {
			console.debug(`被攻击伤害结果 ===> 内丹属性 ${key}`);
			nei_dan_data["被攻击伤害结果"](fight_data, src_unit, target_unit, damage);
		}
	}

	if (target_unit["类型"] === "bb") {
		// TODO 特性影响 受到的所有伤害增加
		if (target_unit["巧劲"]) {
			damage += damage * target_unit["巧劲"][2];
		} else if (target_unit["识药"]) {
			damage += damage * target_unit["识药"][2];
		} else if (target_unit["御风"]) {
			damage += damage * target_unit["御风"][2];
		}
		// TODO 特性影响 受到的所有伤害增加
		if (target_unit["统御属性"] && target_unit["统御属性"]["偃旗息鼓"]) {
			damage = Math.floor(damage * (1 - target_unit["统御属性"]["偃旗息鼓"]));
		}
	}

	if (damage < 1) {
		damage = 1;
	};

	if (target_unit["共生"]) {
		if (cureent_index === 1) {
			//TODO  战斗技能:法术共生计算(战斗数据,编号,目标,Math.floor(伤害),特效,执行数,目标数)
		}
		return;
	}

	// 被攻击单位法术状态伤害反弹
	for (const key in target_unit["法术状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["被攻击法伤反弹"]) {
			console.debug(`被攻击法伤反弹 ===>  法术状态 ${key}`);
			let res = G.SkillData.default[key]["被攻击法伤反弹"](fight_data, src_unit, target_unit, damage);
			if (res) {
				return;
			}
		}
	}
	// 被攻击单位法术状态伤害反弹
	for (const key in target_unit["法术状态"]) {
		if (G.SkillData.default[key] && G.SkillData.default[key]["被攻击法伤反弹"]) {
			console.debug(`被攻击法伤反弹 ===>  法术状态 ${key}`);
			let res = G.SkillData.default[key]["被攻击法伤反弹"](fight_data, src_unit, target_unit, damage);
			if (res) {
				return;
			}
		}
	}

	// 修罗咒被攻击反震计算
	if (target_unit["法术状态"]["修罗咒"]) {
		G.SkillData.default["修罗咒"]["反震计算"](fight_data, src_unit, target_unit, damage);
	}

	if (src_unit["法术状态"]["灵断"] === undefined && damage >= target_unit["气血"] && target_unit["神佑"] && G.RandomUtils.chance(target_unit["神佑"])) {
		damage = target_unit["最大气血"];
		if (target_unit["神佑"] < 30) {
			damage = target_unit["最大气血"] * 0.6;
		}
		if (damage < 1) {
			damage = 1;
		}
		if (target_unit["类型"] === "bb") {
			target_unit["神佑复活"] = true;
		}
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["伤害"] = damage;
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["类型"] = 2;
		return;
	} else if (damage >= target_unit["气血"] && target_unit["法术状态"]["渡劫金身"]) {
		damage = target_unit["法术状态"]["渡劫金身"]["恢复气血"];
		if (damage < 1) {
			damage = 1;
		}
		if (target_unit["类型"] === "bb") {
			target_unit["神佑复活"] = true;
		}
		G.FightComputingUtils.add_target_hp_and_play(fight_data, target_unit, damage);
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["伤害"] = damage;
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["类型"] = 2;
		G.FightStatusUtils.canel_unit_status(fight_data, "渡劫金身", target_unit);
		return;
	}

	let damage_type = 1;

	if (xs) {//技能是否能被吸收
		let is_xs;
		if (xs === "土" && target_unit["土吸"]) {
			is_xs = 1;
		} else if (xs === "水" && target_unit["水吸"]) {
			is_xs = 1;
		} else if (xs === "火" && target_unit["火吸"]) {
			is_xs = 1;
		} else if (xs === "雷" && target_unit["雷吸"]) {
			is_xs = 1;
		}
		if (is_xs) {
			if (G.RandomUtils.chance(30)) {
				damage = Math.floor(damage * 0.3);
				damage_type = 2;
			} else {
				//吸收失败也可减少法术伤害的30%
				damage = Math.floor(damage * 0.7);
			}
		} else if (target_unit["法术状态"]["颠倒五行"]) {
			if (G.RandomUtils.chance(30)) {
				damage = Math.floor(damage * 0.3);
				damage_type = 2;
			}
		} else if (G.FightUnitUtils.check_unit_fa_bao(fight_data, target_unit, "谷玄星盘")) {
			if (G.RandomUtils.chance(Math.floor(G.FightUnitUtils.get_unit_fa_bao_jingjie(target_unit, "谷玄星盘") * 0.7))) {
				damage = Math.floor(damage * 0.3);
				damage_type = 2;
			}
		}
	} else if (target_unit["法术状态"]["分水"] && G.RandomUtils.chance(60)) {
		damage = G.RandomUtils.generate_random(40, target_unit["法术状态"]["分水"]["境界"] * 15);
		damage_type = 2;
	}

	if (damage_type === 1) {
		if (rd) {//好像弱点和吸收是冲突的
			if (rd === "土" && target_unit["弱点土"]) {
				damage = Math.floor(damage * 1.5);
			} else if (rd === "雷" && target_unit["弱点雷"]) {
				damage = Math.floor(damage * 1.5);
			} else if (rd === "火" && target_unit["弱点火"]) {
				damage = Math.floor(damage * 1.5);
			} else if (rd === "水" && target_unit["弱点水"]) {
				damage = Math.floor(damage * 1.5);
			}
		}
		if (target_unit["法术状态"]["护佑"]) {
			damage -= target_unit["法术状态"]["护佑"]["等级"];
		}
		if (target_unit["门派"] === "五庄观") {
			if (G.FightUnitUtils.check_unit_fa_bao(fight_data, target_unit, "奇门五行令")) {
				let jj = G.FightUnitUtils.get_unit_fa_bao_jingjie(target_unit, "奇门五行令")
				damage_ratio = target_unit["气血"] / target_unit["最大气血"];
				if (damage_ratio <= 0.75) {
					if (damage_ratio <= 0.35) {
						damage_ratio = 0.35;
					}
					damage_ratio += (0.3 - 0.02 * jj);
					damage = Math.floor(damage * damage_ratio);
				}
			}
		} else if (target_unit["门派"] === "阴曹地府") {
			if (G.FightUnitUtils.check_fight_unit_jingmai(target_unit, "阴曹地府", "回旋")) {
				damage -= 65;
			}
		} else if (target_unit["门派"] === "凌波城") {
			if (G.FightUnitUtils.check_fight_unit_jingmai(target_unit, "凌波城", "巧变") && target_unit["战意"] >= 4) {
				damage -= 150;
			}
		}
		if (target_unit["法术状态"]["同舟共济"] && target_unit["法术状态"]["同舟共济"]["次数"] > 0) {
			let att_unit = G.FightUtils.get_fight_unit_by_number(fight_data, target_unit["法术状态"]["同舟共济"]["攻击编号"]);
			if (att_unit && att_unit["气血"] > 0) {
				damage = Math.floor(damage * 0.25);
				target_unit["法术状态"]["同舟共济"]["次数"] -= 1;
				G.FightComputingUtils.add_target_hp_and_play(fight_data, target_unit, damage);
			}
		}
	}

	if (damage < 1) { damage = 1 }
	let ap_damage = src_unit["法伤结果"] || 0;
	damage = Math.floor(damage + ap_damage);
	fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["伤害"] = damage;
	fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["类型"] = damage_type;
	G.FightUtils.add_waiting_play_time(fight_data, 2, "固伤技能");

	// 每回合毒掉血处理
	if (target_unit["门派"] === "女儿村") {
		if (G.FightUnitUtils.check_fight_unit_jingmai(target_unit, "女儿村", "轻霜") && src_unit["法术状态"]["毒"] === undefined && G.RandomUtils.chance(30)) {
			G.FightStatusUtils.add_unit_status(fight_data, src_unit, target_unit, "毒", G.FightUnitUtils.get_unit_skill_level("毒经"));
			src_unit["法术状态"]["毒"]["回合掉血"] = G.FightUnitUtils.get_unit_skill_level("毒经") * 3
			src_unit["法术状态"]["毒"]["回合"] = 4;
		}
	}

	if (damage_type === 2) {//恢复状态
		G.FightComputingUtils.add_target_hp_and_play(fight_data, target_unit, damage);
	} else {
		let die = G.FightComputingUtils.computing_remove_hp(fight_data, src_unit, target_unit, damage, skill_name);
		fight_data["战斗流程"][fight_data["战斗流程"].length - 1]["被攻击"][cureent_index]["死亡"] = die;
		//火甲术反击
		if (target_unit["法术状态"]["火甲术"]) {
			G.FightAPSkillUtils.computing_ap_skill(fight_data, target_unit, src_unit, "三昧真火", target_unit["等级"], 0.5);
		}
	}
}